package com.mmm.advert.service.impl;

import com.alibaba.fastjson.JSON;
import com.mmm.advert.entity.Advert;
import com.mmm.advert.dao.AdvertDao;
import com.mmm.advert.service.AdvertService;
import com.mmm.advert.vo.Paging;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * (Advert)表服务实现类
 *
 * @author One
 * @since 2022-02-14 22:55:26
 */
@Service("advertService")
@Transactional
public class AdvertServiceImpl implements AdvertService {
    @Autowired
    private AdvertDao advertDao;

    @Autowired
    private RestHighLevelClient client;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public Advert queryById(Long id) {
        try {
            
            GetRequest request = new GetRequest("rush_advert", id.toString());
            GetResponse documentFields = client.get(request, RequestOptions.DEFAULT);
            String source = documentFields.getSourceAsString();
            return JSON.parseObject(source, Advert.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        throw new RuntimeException("获取广告失败");
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit  查询条数
     * @return 对象列表
     */
    @Override
    public List<Advert> queryAllByLimit(int offset, int limit) {
        return this.advertDao.queryAllByLimit(offset, limit);
    }

    /**
     * 新增数据
     *
     * @param advert 实例对象
     * @return 实例对象
     */
    @Override
    public Advert insert(Advert advert) {
        advert.setCreateTime(new Date());
        advert.setUpdateTime(new Date());
        int insert = this.advertDao.insert(advert);
        if (insert == 1) {
            try {
                IndexRequest request = new IndexRequest("rush_advert").id(advert.getId().toString());
                request.source(JSON.toJSONString(advert), XContentType.JSON);
                client.index(request, RequestOptions.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("advert数据插入错误");
            }
        }
        return advert;
    }

    /**
     * 修改数据
     *
     * @param advert 实例对象
     * @return 实例对象
     */
    @Override
    public Advert update(Advert advert) {
        try {
            advert.setUpdateTime(new Date());
            int i = this.advertDao.update(advert);
            if (i == 1) {
                UpdateRequest rushAdvert = new UpdateRequest("rush_advert", advert.getId().toString());
                rushAdvert.doc(
                        "content", advert.getContent()
                );
                client.update(rushAdvert, RequestOptions.DEFAULT);
            }
            return this.queryById(advert.getId());
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("advert数据更新错误");
        }
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        Advert advert = advertDao.queryById(id);
        advert.setDeleteTime(new Date());
        try {
            DeleteRequest request = new DeleteRequest("rush_advert", advert.getId().toString());
            client.delete(request, RequestOptions.DEFAULT);
        }catch (IOException e){
            e.printStackTrace();
        }
        return this.advertDao.update(advert) > 0;
    }

    @Override
    public Paging<Advert> page(Integer page, Integer size) {
        Paging<Advert> paging = new Paging<>();
        try {
            SearchRequest request = new SearchRequest("rush_advert");
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            request.source().query(boolQueryBuilder)
                    .sort("updateTime", SortOrder.DESC)
                    .size(size)
                    .from(page);
            SearchResponse search = client.search(request, RequestOptions.DEFAULT);
            SearchHit[] hits = search.getHits().getHits();
            List<Advert> list = new ArrayList<>();
            for (SearchHit hit : hits) {
                String source = hit.getSourceAsString();
                Advert advert = JSON.parseObject(source, Advert.class);
                list.add(advert);
            }
            int value = (int) search.getHits().getTotalHits().value;
            int total = size < value ? size : value;
            paging.setTotal((long) total);
            paging.setPage(page);
            paging.setSize(size);
            paging.setTotalPage(value);
            paging.setItems(list);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return paging;
    }

    @Override
    public List<Advert> getAll() {
        return advertDao.getAll();
    }
}